//程序开始
#include<stdio.h>
#include<string.h>
typedef unsigned longULONG;
 
/*
* @Brief:	初始化函数
* @Call:	NULL
* @Param:	1.256长度的char型数组，定义为: unsigned char sBox[256];
					2.密钥，其内容可以随便定义：char key[256];
					3.密钥的长度，Len = strlen(key);
* @Note:	在初始化的过程中，密钥的主要功能是将S-box搅乱，i确保S-box的每个元素都得到处理，j保证S-box的搅乱是随机的。
          而不同的S-box在经过伪随机子密码生成算法的处理后可以得到不同的子密钥序列，将S-box和明文进行xor运算，得到密文，解密过程也完全相同。
* @Return:NULL
*/
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{
  int i = 0, j = 0;
  char k[256] = {0};
  unsigned char tmp = 0;

  /*
  这里就是进行了初始化状态向量S，按照升序进行赋值（256个字节，用来作为密钥流生成的种子1）
  以及对初始密钥进行初始化，如果密钥的长度不足256，进行轮转填满，
  由上述轮转过程得到256个字节的向量T（用来作为密钥流生成的种子2）
  */
  for (i = 0; i < 256; i++)
  {
    s[i] = i;
    k[i] = key[i%Len];
  }

  /*
  开始对向量S进行置换操作，用来打乱初始种子1
  */
  for (i = 0; i < 256; i++)
  {
    j = (j + s[i] + k[i]) % 256;
    tmp = s[i];
    s[i] = s[j];//交换s[i]和s[j]
    s[j] = tmp;
  }
}
 
/*
* @Brief:	加解密
* @Call:	NULL
* @Param:	1.上边rc4_init函数中，被搅乱的S-box;
					2.需要加密的数据data;
					3.data的长度.
* @Note:	
* @Return:NULL
*/
void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
{
  int i = 0, j = 0, t = 0;
  unsigned long k = 0;
  unsigned char tmp;
  for (k = 0; k < Len; k++)
  {
    i = (i + 1) % 256;
    j = (j + s[i]) % 256;
    tmp = s[i];
    s[i] = s[j];//交换s[x]和s[y]
    s[j] = tmp;
    t = (s[i] + s[j]) % 256;//这里就是当前生成的一个秘钥流中的一位

    Data[k] ^= s[t];//可以直接在这里进行加密，当然也可以将密钥流保存在数组中，最后进行异或就ok
  }
}
unsigned char pData[1024] = "{\" device_id \":\" test - carego - 2 \",\" positions \":[{\" longitude \":4396,\" latitude \":4396,\" minor \":2,\" time \":1617001102,\" event_id \":\" abababababa4 - xx \",\" status \":2}]}";



int main()
{
  unsigned char s[256] = {0}, s2[256] = {0};//S-box
  unsigned char key[256] = {"justfortest"};
  // unsigned char pData[1024] = "ThisisaDataString";
  unsigned long len = strlen(pData);
  int i;

  printf("pData = %s\n", pData);
  printf("key = %s,length = %ld\n\n", key, strlen(key));
  
  rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化
  printf("完成对S[i]的初始化，如下：\n\n");
  for (i = 0; i<256; i++)
  {
    printf("%02X", s[i]);
    if (i && (i + 1) % 16 == 0)putchar('\n');
  }
  printf("\n\n");

  for (i = 0; i < 256; i++)//用s2[i]暂时保留经过初始化的s[i]，很重要的！！！
  {
    s2[i] = s[i];
  }

  printf("已经初始化，现在加密:\n\n");
  rc4_crypt(s, (unsigned char*)pData, len);//加密
  printf("pData=%s\r\n-----------\r\n", pData);

  for (size_t i = 0; i < strlen(pData); i++)
  {
    printf("%d ", pData[i]);
  }
  printf("\r\n----------\r\n");
  for (size_t i = 0; i < strlen(pData); i++)
  {
    printf("%x", pData[i]);
  }
  printf("\r\n----------\r\n");

  printf("已经加密，现在解密:\n\n");

  //rc4_init(s,(unsignedchar*)key,strlen(key));//初始化密钥
  rc4_crypt(s2, (unsigned char*)pData, len);//解密
  printf("pData=%s\n\n", pData);
  return 0;
}
 
//程序完
